﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http;
using ThresholdAssistant.DataContract.Headers;
using ThresholdAssistant.Enums;

namespace ThresholdAssistant.Tools.Extensions
{
    /// <summary>
    /// 字典类型扩展
    /// </summary>
    public static class DictionaryExtensions
    {
        /// <summary>
        /// 获取对应字典对象的值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="keys"></param>
        /// <returns></returns>
        public static string GetValue(this IDictionary<string, string> source, params string[] keys)
        {
            var result = "";
            if (keys == null || !keys.Any())
            {
                return default;
            }

            foreach (var key in keys)
            {
                result = source.GetValue(key);
                if (!string.IsNullOrEmpty(result))
                {
                    break;
                }
            }
            return result;
        }

        /// <summary>
        /// 获取对应字典对象的值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="keys"></param>
        /// <returns></returns>
        public static T GetValue<T>(this IDictionary<string, string> source, params string[] keys)
        {
            T result = default;
            if (keys == null || !keys.Any())
            {
                return default;
            }

            foreach (var key in keys)
            {
                var value = source.GetValue(key);
                if (!string.IsNullOrEmpty(value))
                {
                    result = value.ToObject<T>();
                    break;
                }
            }
            return result;
        }

        /// <summary>
        /// 获取对应字典对象的值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetValue<T>(this IDictionary<string, string> source, string key)
        {
            var value = source.GetValue(key);
            return value.ToObject<T>();
        }

        /// <summary>
        /// 获取对应字典对象的值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetValue(this IDictionary<string, string> source, string key)
        {
            return source.GetValue<string, string>(key) ?? "";
        }

        /// <summary>
        /// 获取配置信息
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="source"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static TValue GetValue<TKey, TValue>(this IDictionary<TKey, TValue> source, TKey key)
        {
            TValue result = default;
            if (source == null || !source.Any())
            {
                return result;
            }

            if (source.ContainsKey(key))
            {
                result = source[key];
            }
            return result;
        }

        /// <summary>
        /// 获取参数字段值
        /// </summary>
        /// <param name="actionArguments">行为参数</param>
        /// <param name="fieldNames">字段名称</param>
        /// <returns></returns>
        public static T GetActionArgumentValue<T>(this IDictionary<string, object> actionArguments, params string[] fieldNames)
        {
            var actionArgumentValue = actionArguments.GetActionArgumentValue(fieldNames);
            return actionArgumentValue.ToObject<T>();
        }

        /// <summary>
        /// 获取参数字段值
        /// </summary>
        /// <param name="actionArguments">行为参数</param>
        /// <param name="fieldNames">字段名称</param>
        /// <returns></returns>
        public static string GetActionArgumentValue(this IDictionary<string, object> actionArguments, params string[] fieldNames)
        {
            var actionArgumentValue = "";
            if (actionArguments == null || !actionArguments.Any() || fieldNames == null || !fieldNames.Any())
                return actionArgumentValue;

            foreach (var actionArgument in actionArguments)
            {
                if (actionArgument.Value == null)
                    continue;

                var type = actionArgument.Value.GetType();
                var actionArgumentInfo = actionArgument.Value;
                if (actionArgumentInfo == null)
                    continue;

                if (type.IsClass && !"string".Equals(type.Name.ToLower()))
                {
                    actionArgumentValue = actionArgumentInfo.GetPropertyValue<string>(fieldNames);
                }
                else
                {
                    foreach (var fieldName in fieldNames)
                    {
                        if (actionArgument.Value == null)
                            continue;

                        if (actionArgument.Key == fieldName)
                        {
                            actionArgumentValue = actionArgument.Value.ToString();
                            if (!string.IsNullOrEmpty(actionArgumentValue))
                                break;
                        }
                    }
                }

                if (!string.IsNullOrEmpty(actionArgumentValue))
                    break;
            }
            return actionArgumentValue;
        }

        /// <summary>
        /// 获取企微头部信息
        /// </summary>
        /// <param name="headers">头部信息</param>
        /// <returns></returns>
        public static WorkRobotHeader GetWorkRobotHeader(this IHeaderDictionary headers)
        {
            WorkRobotHeader header = null;
            if (headers != null && headers.Any())
            {
                header = new WorkRobotHeader()
                {
                    DeviceNo = headers.GetValue("device-no"),
                    Sign = headers.GetValue("sign"),
                    RobotId = headers.GetValue("robot-id"),
                    AppVersion = headers.GetValue("robot-version"),
                    RobotType = headers.GetValue("robot-type"),
                    Method = headers.GetValue("method"),
                    ProtocolType = headers.GetValue("protocol-type"),
                    WxVersion = headers.GetValue("work-version"),
                    Multiterminal = headers.GetValue("multi-terminal") == "1"
                };
            }
            return header;
        }

        /// <summary>
        /// 获取头部信息
        /// </summary>
        /// <param name="headers">头部信息</param>
        /// <returns></returns>
        public static RobotHeader GetRobotHeader(this IDictionary<string, string> headers)
        {
            RobotHeader model = null;
            if (headers != null && headers.Any())
            {
                model = new RobotHeader();
                if (headers.ContainsKey("robot-type"))
                {
                    var robotType = headers["robot-type"];
                    model.ProtocolType = ConvertProtocolType(robotType);
                }
                if (headers.ContainsKey("robot-version"))
                {
                    model.RobotVersion = headers["robot-version"];
                }
                if (headers.ContainsKey("wx-protocol-type"))
                {
                    model.WxProtocolType = headers["wx-protocol-type"];
                }
                if (headers.ContainsKey("wx-short-version"))
                {
                    model.WxShortWersion = headers["wx-short-version"];
                }
                if (headers.ContainsKey("wx-app-version"))
                {
                    model.WxAppWersion = headers["wx-app-version"];
                }
                if (headers.ContainsKey("device-no"))
                {
                    model.DeviceNo = headers["device-no"];
                }
                if (headers.ContainsKey("device-user-serial-no"))
                {
                    model.DeviceUserSerialNo = headers["device-user-serial-no"];
                }
                if (headers.ContainsKey("robot-wxid"))
                {
                    model.RobotWxId = headers["robot-wxid"];
                }
                if (headers.ContainsKey("sign"))
                {
                    model.Sign = headers["sign"];
                }
                if (headers.ContainsKey("method"))
                {
                    model.Method = headers["method"];
                }
            }
            return model;
        }

        /// <summary>
        /// 协议转换
        /// </summary>
        /// <param name="robotType">机器人类型</param>
        /// <returns></returns>
        private static RobotProtocolType ConvertProtocolType(string robotType)
        {
            switch (robotType)
            {
                case "ios_protocol":
                    return RobotProtocolType.iPhone;
                case "android_protocol":
                    return RobotProtocolType.Android;
                case "android_emulator":
                    return RobotProtocolType.AndroidSimulator;
                case "android_box":
                    return RobotProtocolType.android_box;
                case "windows":
                    return RobotProtocolType.windows;
                case "windows_guard":
                    return RobotProtocolType.windows_guard;
                case "windows_protocol":
                    return RobotProtocolType.windows_protocol;
                case "windows_pdd":
                    return RobotProtocolType.windows_pdd;
                case "az_protocol":
                    return RobotProtocolType.az_protocol;
                case "mac_protocol":
                    return RobotProtocolType.mac_protocol;
                case "android_pad_protocol":
                    return RobotProtocolType.android_pad_protocol;
                case "cloud_protocol":
                    return RobotProtocolType.cloud_protocol;
                case "windows_local":
                    return RobotProtocolType.windows_local;
            }
            throw new ArgumentException("PushTargetType参数robotType异常");
        }

        /// <summary>
        /// 获取头部信息
        /// </summary>
        /// <param name="headers">头部信息</param>
        /// <returns></returns>
        public static RobotHeaderModel ToRobotHeader(this IHeaderDictionary headers)
        {
            var headerDic = headers.ToDictionary(k => k.Key, v => v.Value.ToString());
            return headerDic.ToRobotHeader();
        }

        /// <summary>
        /// 转换机器人头部信息
        /// </summary>
        /// <param name="headers">头部信息</param>
        /// <returns></returns>
        public static RobotHeaderModel ToRobotHeader(this IDictionary<string, string> headers)
        {
            RobotHeaderModel robotHeaderInfo = null;
            if (headers != null && headers.Any())
            {
                Enum.TryParse(headers.GetValue("device_type", "device-type"), out DeviceTypeEnum deviceType);
                Enum.TryParse(headers.GetValue("protocol_type", "protocol-type"), out RobotProtocolType protocolType);
                robotHeaderInfo = new RobotHeaderModel()
                {
                    DeviceType = deviceType,
                    ProtocolType = protocolType,
                    Sign = headers.GetValue("sign"),
                    RobotId = headers.GetValue("robot_id", "robot-id"),
                    DeviceNo = headers.GetValue("device_no", "device-no"),
                    AppVersion = headers.GetValue("app_version", "app-version"),
                    LargeVersion = headers.GetValue("large_version", "large-version"),
                    SmallVersion = headers.GetValue("small_version", "small-version"),
                    UserSerialNo = headers.GetValue("user_serial_no", "user-serial-no")
                };
            }
            return robotHeaderInfo;
        }
    }
}